package com.sunda.spmsorder.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunda.spmscommon.ResponseResult;
import com.sunda.spmscommon.service.ISysLogService;
import com.sunda.spmsorder.entity.MaterialApplication;
import com.sunda.spmsorder.entity.MaterialApplicationDtl;
import com.sunda.spmsorder.entity.vo.MaterialApplicationQueryResultVo;
import com.sunda.spmsorder.entity.vo.MaterialApplicationQueryVo;
import com.sunda.spmsorder.mapper.MaterialApplicationMapper;
import com.sunda.spmsorder.service.IFileOperationService;
import com.sunda.spmsorder.service.IMaterialApplicationDtlService;
import com.sunda.spmsorder.service.IMaterialApplicationService;
import com.sunda.spmsorder.service.IOrderLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;

import java.text.SimpleDateFormat;
import java.util.*;

import static com.sunda.spmscommon.Constans.*;

/**
 * <p>
 * 物料申请单表表头 服务实现类
 * </p>
 *
 * @author Wayne
 * @since 2021-05-21
 */
@Service
public class MaterialApplicationServiceImpl extends ServiceImpl<MaterialApplicationMapper, MaterialApplication> implements IMaterialApplicationService {

    @Autowired
    IMaterialApplicationDtlService iMaterialApplicationDtlService;

    @Autowired
    IOrderLogService iOrderLogService;

    @Autowired
    IFileOperationService iFileOperationService;

    @Autowired
    ISysLogService iSysLogService;

    @Override
    public List<MaterialApplicationQueryResultVo> getMaterialApplicationList(MaterialApplicationQueryVo materialApplicationQueryVo) {
        return this.baseMapper.getMaterialApplicationList(materialApplicationQueryVo);
    }

    @Override
    public Page<MaterialApplicationQueryResultVo> getPageMaterialApplication(MaterialApplicationQueryVo materialApplicationQueryVo) {
        int pageNo = materialApplicationQueryVo.getPageNo() == null ? 1 : materialApplicationQueryVo.getPageNo();
        int pageSize = materialApplicationQueryVo.getPageSize() == null ? 20 : materialApplicationQueryVo.getPageSize();
        Page<MaterialApplicationQueryResultVo> pages = new Page<>(pageNo, pageSize);
        List<MaterialApplicationQueryResultVo> pageMaData = this.baseMapper.pageMaData(pages, materialApplicationQueryVo);
        pages.setRecords(pageMaData);
        return pages;
    }

    @Override
    public Page<Map<String, Object>> getPageMap(JSONObject doc) {
        int pageNo = !doc.containsKey("pageNo") || doc.get("pageNo") == null || "".equals(doc.get("pageNo")) ? 1 : Integer.parseInt(doc.get("pageNo").toString());
        int pageSize = !doc.containsKey("pageSize") || doc.get("pageSize") == null || "".equals(doc.get("pageSize")) ? 20 : Integer.parseInt(doc.get("pageSize").toString());

        String applicationId = !doc.containsKey("applicationId") || doc.get("applicationId") == null || "".equals(doc.get("applicationId")) ? null : doc.getString("applicationId");
        String spmsStatus = !doc.containsKey("spmsStatus") || doc.get("spmsStatus") == null || "".equals(doc.get("spmsStatus")) ? null : doc.getString("spmsStatus");
        String userId = !doc.containsKey("userId") || doc.get("userId") == null || "".equals(doc.get("userId")) ? null : doc.getString("userId");
        String werks = !doc.containsKey("werks") || doc.get("werks") == null || "".equals(doc.get("werks")) ? null : doc.getString("werks");
        String workshopCode = !doc.containsKey("workshopCode") || doc.get("workshopCode") == null || "".equals(doc.get("workshopCode")) ? null : doc.getString("workshopCode");
        String beginDate = !doc.containsKey("beginDate") || doc.get("beginDate") == null || "".equals(doc.get("beginDate")) ? null : doc.getString("beginDate");
        String endDate = !doc.containsKey("endDate") || doc.get("endDate") == null || "".equals(doc.get("endDate")) ? null : doc.getString("endDate");

        Page<Map<String, Object>> pages = new Page<>(pageNo, pageSize);
        List<Map<String, Object>> pageMaData = this.baseMapper.pageMaDataMap(pages, applicationId, spmsStatus, userId, werks, workshopCode, beginDate, endDate);
        pages.setRecords(pageMaData);
        return pages;
    }

    @Override
    public List<MaterialApplicationDtl> getMaterialApplicationDtlList(String applicationUuid) {
        return iMaterialApplicationDtlService.getMaterialApplicationDtlList(applicationUuid);
    }

    /**
     {
     "materialApplication": {
     "applicationUuid": "123456",
     "applicationType": "1",
     "updateTime": "2021-05-26 02:45:42",
     "userId": "999947",
     "werks": "GF03",
     "createTime": "2021-05-26 02:45:42",
     "spmsStatus": "1",
     "workshopCode": "RM",
     "applicationId": "GF03-RM-001",
     "remarks": null,
     "username": "吴敏",
     "applicationDate": "2021-05-26"
     },
     "materialApplicationDtl": [{
     "applicationUuid": "123456",
     "applicationItem": "10",
     "materialEnDesc": "123",
     "specs": "123",
     "basicUnit": "12",
     "materialModel": null,
     "supplierMaterialNo": null,
     "supplyDesc": null,
     "relateEquipment": null,
     "equipmentSpec": null,
     "equipemntSupplier": null,
     "equipmentBrand": null,
     "productLevelLargeDesc": null,
     "productLevelMidDesc": null,
     "productLevelSmallDesc": null,
     "picture": null,
     "remarks": null,
     "autoId": 1
     },
     {
     "applicationUuid": "123456",
     "applicationItem": "20",
     "materialEnDesc": "234",
     "specs": "21",
     "basicUnit": "12",
     "materialModel": null,
     "supplierMaterialNo": null,
     "supplyDesc": null,
     "relateEquipment": null,
     "equipmentSpec": null,
     "equipemntSupplier": null,
     "equipmentBrand": null,
     "productLevelLargeDesc": null,
     "productLevelMidDesc": null,
     "productLevelSmallDesc": null,
     "picture": null,
     "remarks": null,
     "autoId": 2
     }]}
     * @param doc
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized ResponseResult addMaAndDtl(JSONObject doc, String userId) {
        try {
            ResponseResult responseResult = checkDataValidate(doc);
            if (responseResult.getCode() != 200){
                return responseResult;
            }
            String uuid = UUID.randomUUID().toString().replaceAll("-","").toLowerCase();
            String materialApplicationDtlUuid = "";
            JSONObject object = doc.getJSONObject("materialApplication");
            JSONArray dtlArray = doc.getJSONArray("materialApplicationDtl");
            String applicationUuid = object.getString("applicationUuid");
            String spmsStatus = object.getString("spmsStatus");


            MaterialApplication application = StringUtils.isEmpty(applicationUuid) ?
                    null : this.baseMapper.selectOne(new QueryWrapper<MaterialApplication>().eq("APPLICATION_UUID", applicationUuid));
            MaterialApplication materialApplication = new MaterialApplication();
//            materialApplication.setUserId(userId);
//            materialApplication.setWerks(object.getString("werks"));
//            materialApplication.setWorkshopCode(object.getString("workshopCode"));
            materialApplication.setApplicationType(object.getString("applicationType"));
            materialApplication.setSpmsStatus(object.getString("spmsStatus"));
            materialApplication.setRemarks(object.getString("remarks"));
//            materialApplication.setApplicationDate(object.getString("applicationDate"));
            materialApplication.setCpx(object.getString("cpx"));
            if (application == null){
                materialApplication.setApplicationUuid(uuid);
                materialApplication.setUserId(userId);
                materialApplication.setWerks(object.getString("werks"));
                materialApplication.setWorkshopCode(object.getString("workshopCode"));
                materialApplication.setApplicationDate(object.getString("applicationDate"));
                this.baseMapper.insert(materialApplication);
                iOrderLogService.saveOrderLog(userId, MATERIAL_APPLICATION_INIT, uuid);
                materialApplicationDtlUuid = uuid;
            }else {
                if ("2".equals(application.getSpmsStatus())){
                    return ResponseResult.error("单据已提交请勿重复操作");
                }
                this.baseMapper.update(materialApplication, new QueryWrapper<MaterialApplication>().eq("APPLICATION_UUID", applicationUuid));
                iMaterialApplicationDtlService.deleteMaterialApplicationDtls(applicationUuid);
                if ("1".equals(spmsStatus)){
                    iOrderLogService.saveOrderLog(userId, MATERIAL_APPLICATION_UPDATE, applicationUuid);
                }
                if ("2".equals(spmsStatus)){
                    iOrderLogService.saveOrderLog(userId, MATERIAL_APPLICATION_SUBMIT, applicationUuid);
                }
                materialApplicationDtlUuid = applicationUuid;
            }
            List<MaterialApplicationDtl> materialApplicationDtlArr = new ArrayList<>();
            for (int i = 0; i < dtlArray.size(); i ++){
                JSONObject dtl = dtlArray.getJSONObject(i);
                MaterialApplicationDtl materialApplicationDtl = new MaterialApplicationDtl();
                materialApplicationDtl.setApplicationUuid(materialApplicationDtlUuid);
                materialApplicationDtl.setApplicationItem(String.valueOf((i + 1) * 10));
                materialApplicationDtl.setMaterialEnDesc(dtl.getString("materialEnDesc"));
                materialApplicationDtl.setSpecs(dtl.getString("specs"));
                materialApplicationDtl.setBasicUnit(dtl.getString("basicUnit"));
                materialApplicationDtl.setMaterialModel(dtl.getString("materialModel"));
                materialApplicationDtl.setSupplierMaterialNo(dtl.getString("supplierMaterialNo"));
                materialApplicationDtl.setSupplyDesc(dtl.getString("supplyDesc"));
                materialApplicationDtl.setRelateEquipment(dtl.getString("relateEquipment"));
                materialApplicationDtl.setEquipmentSpec(dtl.getString("equipmentSpec"));
                materialApplicationDtl.setEquipmentSupplier(dtl.getString("equipmentSupplier"));
                materialApplicationDtl.setEquipmentBrand(dtl.getString("equipmentBrand"));
                materialApplicationDtl.setProductLevelLargeDesc(dtl.getString("productLevelLargeDesc"));
                materialApplicationDtl.setProductLevelMidDesc(dtl.getString("productLevelMidDesc"));
                materialApplicationDtl.setProductLevelSmallDesc(dtl.getString("productLevelSmallDesc"));
                materialApplicationDtl.setPicture(dtl.getString("picture"));
                materialApplicationDtl.setRemarks(dtl.getString("remarks"));
                materialApplicationDtl.setPurchaseUsername(dtl.getString("purchaseUsername"));
                materialApplicationDtl.setThirdPartyPlatform(dtl.getString("thirdPartyPlatform"));
                materialApplicationDtl.setLink(dtl.getString("link"));
                materialApplicationDtl.setSku(dtl.getString("sku"));
                materialApplicationDtl.setSpareField(dtl.getString("spareField"));
                materialApplicationDtlArr.add(materialApplicationDtl);
                iMaterialApplicationDtlService.insertMaterialApplicationDtl(materialApplicationDtl);
            }
            if (application == null){
                return ResponseResult.success()
                        .add("materialApplication", this.baseMapper.selectOne(new QueryWrapper<MaterialApplication>().eq("APPLICATION_UUID", uuid)))
                        .add("getMaterialApplicationDtlList", getMaterialApplicationDtlList(uuid));
            }else {
                return ResponseResult.success()
                        .add("materialApplication", this.baseMapper.selectOne(new QueryWrapper<MaterialApplication>().eq("APPLICATION_UUID", applicationUuid)))
                        .add("getMaterialApplicationDtlList", getMaterialApplicationDtlList(applicationUuid));
            }
        }catch (Exception e){
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseResult.error("请求错误");
        }
    }

    @Override
    public ResponseResult getMaAndDtlExcel(JSONObject doc, String userId) {
        String applicationUuid = doc.getString("applicationUuid");
        MaterialApplication materialApplication = this.baseMapper.selectOne(new QueryWrapper<MaterialApplication>().eq("APPLICATION_UUID", applicationUuid));
        // 校验申请单
        if (null == materialApplication ||  materialApplication.getSpmsStatus().equals("2")){
            return ResponseResult.error("物料申请单不存在或状态错误");
        }
        List<MaterialApplicationDtl> materialApplicationDtlArr = getMaterialApplicationDtlList(applicationUuid);
        // 20210629 xpw 生成Excel物料申请附件
        String filename = "material_application_" + applicationUuid +"_" + System.currentTimeMillis()+".xlsx";
        // 1.附件缓存路径
        String excelPath = iFileOperationService.saveMaterialApplicationExcel(materialApplication, materialApplicationDtlArr, filename);
        if (excelPath.isEmpty()){
            return ResponseResult.error("附件创建失败");
        }
        System.out.println("附件缓存地址：" + excelPath);
        // 2.上传附件至minIO文件服务器
        String fileUrl = iFileOperationService.fileUploader(filename, excelPath);
        if (fileUrl.isEmpty()){
            return ResponseResult.error("附件上传失败:" + excelPath + "--" + fileUrl);
        }
        System.out.println("附件上传地址:" + fileUrl);
        // 3.返回附件地址，上传OA
        return ResponseResult.success()
                .add("materialApplication",materialApplication)
                .add("getMaterialApplicationDtlList", materialApplicationDtlArr)
                .add("filename", filename)
                .add("fileUrl",fileUrl);
    }

    @Override
    public ResponseResult updateMaterialApplicationSubmitOaStatus(JSONObject doc, int oaId, String userId) {
        String applicationUuid = doc.getString("applicationUuid");
        MaterialApplication materialApplication = this.baseMapper.selectOne(new QueryWrapper<MaterialApplication>().eq("APPLICATION_UUID", applicationUuid));
        materialApplication.setSpmsStatus("2");
        materialApplication.setRemarks(oaId + "");
        materialApplication.setOaBianhao(String.valueOf(oaId));
        materialApplication.setOaDate(new Date());
        this.baseMapper.update(materialApplication, new QueryWrapper<MaterialApplication>().eq("APPLICATION_UUID", applicationUuid));
        return ResponseResult.success();
    }

    @Override
    public ResponseResult uploadMaterialApplicationPic(MultipartFile multipartFile) {
        // 另存文件名
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
        Calendar calendar = Calendar.getInstance();
        String fileName = df.format(calendar.getTime()) + multipartFile.getOriginalFilename();
        // 1.附件缓存路径
        String filePath = iFileOperationService.saveMaterialApplicationPic(multipartFile, fileName);
        System.out.println("fileName" + filePath);
        // 2.上传附件至minIO文件服务器
        String fileUrl = iFileOperationService.fileUploader(fileName, filePath);
        return ResponseResult.success()
                .add("imageUrl",fileUrl);
    }

    ResponseResult checkDataValidate(JSONObject doc){
        try {
            if (!doc.containsKey("materialApplication") || !doc.containsKey("materialApplicationDtl") ||
                    doc.getJSONArray("materialApplicationDtl").size() == 0){
                return ResponseResult.error("请求参数错误请重试");
            }
            JSONObject materialApplication = doc.getJSONObject("materialApplication");
            if (
                    StringUtils.isEmpty(materialApplication.getString("werks")) ||
                    StringUtils.isEmpty(materialApplication.getString("workshopCode")) ||
                    StringUtils.isEmpty(materialApplication.getString("spmsStatus"))) {
                return ResponseResult.error("请求参数错误请重试");
            }
            return ResponseResult.success();
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error();
        }
    }

    //物料回填物料号
    @Override
    public ResponseResult setBom(JSONObject doc, String userId){
        try {
            ResponseResult responseResult = checkDataValidate(doc);
            if (responseResult.getCode() != 200){
                return responseResult;
            }
            String uuid = UUID.randomUUID().toString().replaceAll("-","").toLowerCase();
            String materialApplicationDtlUuid = "";
            JSONObject object = doc.getJSONObject("materialApplication");
            JSONArray dtlArray = doc.getJSONArray("materialApplicationDtl");
            String applicationUuid = object.getString("applicationUuid");
            String spmsStatus = object.getString("spmsStatus");

            MaterialApplication application = this.baseMapper.selectOne(new QueryWrapper<MaterialApplication>().eq("APPLICATION_UUID", applicationUuid));

            MaterialApplication materialApplication = new MaterialApplication();
            materialApplication.setReviewId(userId);
//            materialApplication.setUserId(userId);
//            materialApplication.setWerks(object.getString("werks"));
//            materialApplication.setWorkshopCode(object.getString("workshopCode"));
            materialApplication.setApplicationType(object.getString("applicationType"));
            materialApplication.setSpmsStatus(object.getString("spmsStatus"));
            materialApplication.setRemarks(object.getString("remarks"));
//            materialApplication.setApplicationDate(object.getString("applicationDate"));
            /** 申请人、申请工厂、申请车间、申请单创建日期，信息属于创建时的初始属性，忽略这几个字段更新———— Wayne 20210917 */
            if (application == null){
                materialApplication.setApplicationUuid(uuid);
                this.baseMapper.insert(materialApplication);
                iOrderLogService.saveOrderLog(userId, MATERIAL_APPLICATION_INIT, uuid);
                materialApplicationDtlUuid = uuid;
            }else {
                this.baseMapper.update(materialApplication, new QueryWrapper<MaterialApplication>().eq("APPLICATION_UUID", applicationUuid));
                iMaterialApplicationDtlService.deleteMaterialApplicationDtls(applicationUuid);
                if ("1".equals(spmsStatus)){
                    iOrderLogService.saveOrderLog(userId, MATERIAL_APPLICATION_UPDATE, applicationUuid);
                }
                if ("2".equals(spmsStatus)){
                    iOrderLogService.saveOrderLog(userId, MATERIAL_APPLICATION_SUBMIT, applicationUuid);
                }
                materialApplicationDtlUuid = applicationUuid;
            }

            for (int i = 0; i < dtlArray.size(); i ++){
                JSONObject dtl = dtlArray.getJSONObject(i);
                MaterialApplicationDtl materialApplicationDtl = new MaterialApplicationDtl();
                materialApplicationDtl.setApplicationUuid(materialApplicationDtlUuid);
                materialApplicationDtl.setApplicationItem(String.valueOf((i + 1) * 10));
                materialApplicationDtl.setMaterialEnDesc(dtl.getString("materialEnDesc"));
                materialApplicationDtl.setSpecs(dtl.getString("specs"));
                materialApplicationDtl.setBasicUnit(dtl.getString("basicUnit"));
                materialApplicationDtl.setMaterialModel(dtl.getString("materialModel"));
                materialApplicationDtl.setSupplierMaterialNo(dtl.getString("supplierMaterialNo"));
                materialApplicationDtl.setSupplyDesc(dtl.getString("supplyDesc"));
                materialApplicationDtl.setRelateEquipment(dtl.getString("relateEquipment"));
                materialApplicationDtl.setEquipmentSpec(dtl.getString("equipmentSpec"));
                materialApplicationDtl.setEquipmentSupplier(dtl.getString("equipmentSupplier"));
                materialApplicationDtl.setEquipmentBrand(dtl.getString("equipmentBrand"));
                materialApplicationDtl.setProductLevelLargeDesc(dtl.getString("productLevelLargeDesc"));
                materialApplicationDtl.setProductLevelMidDesc(dtl.getString("productLevelMidDesc"));
                materialApplicationDtl.setProductLevelSmallDesc(dtl.getString("productLevelSmallDesc"));
                materialApplicationDtl.setPicture(dtl.getString("picture"));
                materialApplicationDtl.setRemarks(dtl.getString("remarks"));
                materialApplicationDtl.setMaterialNo(dtl.getString("materialNo"));
                materialApplicationDtl.setSpareField(dtl.getString("spareField"));
                iMaterialApplicationDtlService.insertMaterialApplicationDtl(materialApplicationDtl);
            }
            if (application == null){
                return ResponseResult.success()
                        .add("materialApplication", this.baseMapper.selectOne(new QueryWrapper<MaterialApplication>().eq("APPLICATION_UUID", uuid)))
                        .add("getMaterialApplicationDtlList", getMaterialApplicationDtlList(uuid));
            }else {
                return ResponseResult.success()
                        .add("materialApplication", this.baseMapper.selectOne(new QueryWrapper<MaterialApplication>().eq("APPLICATION_UUID", applicationUuid)))
                        .add("getMaterialApplicationDtlList", getMaterialApplicationDtlList(applicationUuid));
            }
        }catch (Exception e){
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseResult.error("请求错误");
        }
    }

    @Override
    public List<Map<String, Object>> getOrderLogList(String uuid) {
        return iOrderLogService.getOrderLogList(uuid);
    }

    @Override
    public ResponseResult deleteMaAndDtl(String applicationUuid) {
        if (StringUtils.isEmpty(applicationUuid)){
            return ResponseResult.error("请求参数错误请重试");
        }
        QueryWrapper<MaterialApplication> queryWrapper =
                new QueryWrapper<MaterialApplication>().eq("APPLICATION_UUID", applicationUuid);
        MaterialApplication materialApplication = this.baseMapper.selectOne(queryWrapper);
        if (materialApplication == null){
            return ResponseResult.error("请求单据不存在请刷新重试");
        }
        materialApplication.setSpmsStatus("0");
        this.baseMapper.update(materialApplication,queryWrapper);
        iSysLogService.addSysLog("5","物料申请","删除",materialApplication.getUserId(),"","deleteMaAndDtl","/materialApplication/deleteMaterialApplication","POST","",materialApplication.toString(),"","");
        if ("2".equals(materialApplication.getSpmsStatus())){
            return ResponseResult.error("单据已提交不可删除");
        }
        iMaterialApplicationDtlService.deleteMaterialApplicationDtls(applicationUuid);
        return ResponseResult.success();
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateMaterialApplicationStatus(String userId, String oaBianhao, String oaStatus) {
        if (StringUtils.isEmpty(oaBianhao) || StringUtils.isEmpty(oaStatus)){
            return 0;
        }
        try {
            MaterialApplication materialApplication = this.baseMapper.selectOne(new QueryWrapper<MaterialApplication>().eq("OA_BIANHAO", oaBianhao));
            if (materialApplication == null || materialApplication.toString().length() == 0){
                return 0;
            }
            if ("4".equals(materialApplication.getSpmsStatus())){
                return -2;  //已经审批通过了的，禁止重复提交审批
            }
            if ("S".equals(oaStatus)){
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                String oaApprovalDate = sdf.format(new Date());
                materialApplication.setSpmsStatus("4"); //3 OA审批通过状态
                materialApplication.setOaApprovalDate(oaApprovalDate);
                int resp = this.baseMapper.update(materialApplication, new QueryWrapper<MaterialApplication>().eq("OA_BIANHAO", oaBianhao));
                /** 审批通过，添加物料申请单日志信息 */
                iOrderLogService.saveOrderLog(userId, OA_APPROVED, materialApplication.getApplicationUuid());
                return resp;
            }else {
                materialApplication.setSpmsStatus("5"); //4 OA审批不通过状态
                int resp = this.baseMapper.update(materialApplication, new QueryWrapper<MaterialApplication>().eq("OA_BIANHAO", oaBianhao));
                /** 审批不通过，添加物料申请单日志信息 */
                iOrderLogService.saveOrderLog(userId, OA_REJECT, materialApplication.getApplicationUuid());
                return -1;
            }
        }catch (Exception e){
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return 0;
        }
    }
}
